package com.espirit.finance.core;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.espirit.EntityMapping;
import com.espirit.eap.ICheckModelDuplicateInfo;
import com.espirit.eap.PinyinAware;
import com.espirit.eap.annotation.Dict;
import com.espirit.eap.annotation.ModelDisplayProperty;
import com.googlecode.cswish.annotation.QLFormula;
import com.googlecode.cswish.model.Saas;

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@ModelDisplayProperty("name")
@BatchSize(size=15)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Acct extends EntityMapping implements Serializable,Flag, PinyinAware, ICheckModelDuplicateInfo, Saas{
	private static final long serialVersionUID = 1154171500047794720L;
	public static final String DC= "acct_dc";
	public static final Integer DC_DEBIT = 1;
	public static final Integer DC_CREDIT = -1;
	
	public static final String ACCT_CALC_STRATEGY = "acct_calc_strategy";
	public static final Integer STRATEGY_GENERAL = 1;
	public static final Integer STRATEGY_FIXED = 2;

	private Integer sid;
	public Integer getSid() {
		return sid;
	}

	public void setSid(Integer sid) {
		this.sid = sid;
	}
	

	@Dict(type=DC)
	public Integer getDc() {
		return dc;
	}
	public void setDc(Integer dc) {
		this.dc = dc;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Dict(type=ACCT_CALC_STRATEGY)
	public Integer getStrategy() {
		return strategy;
	}
	public void setStrategy(Integer strategy) {
		this.strategy = strategy;
	}

	@OneToMany(targetEntity = AcctItem.class ,orphanRemoval = true, fetch=FetchType.LAZY,  cascade = CascadeType.ALL, mappedBy = "parent")
	public List<AcctItem> getChildren() {
		return children;
	}
	public void setChildren(List<AcctItem> children) {
		this.children = children;
	}

	public List<AcctItem> safeChildren() {
		if (children == null){
			children = new ArrayList<AcctItem>();
		}
		return children;
	}
	
	@Dict(type=Acct.ACTIVE)
	public Integer getActive() {
		return active;
	}
	public void setActive(Integer active) {
		this.active = active;
	}

	public String getRemark() {
		return remark;
	}
	public void setRemark(String remark) {
		this.remark = remark;
	}

	public String getPinyin() {
		return pinyin;
	}
	public void setPinyin(String pinyin) {
		this.pinyin = pinyin;
	}
	
	public Integer getNbr() {
		return nbr;
	}
	public void setNbr(Integer nbr) {
		this.nbr = nbr;
	}

	private String name;
	private Integer dc; // d(debit) = 1; c(credit) = -1;
	private Integer strategy;
	private List<AcctItem> children;
	private Integer active;
	private String remark;
	private String pinyin;
	private Integer nbr;
	
	
	@Transient
	@QLFormula(value = "active", type = Integer.class)
	public String getActiveFlag() {
		if (this.active == null ){
			return ACTIVE_NO.toString();
		} 
		return this.active.toString();
	}
	
	@Override
	public String source() {
		return name;
	}
	
	private final static String[] gatherProperties = new String[]{"name"};
	@Override
	public String[] gatherProperties() {
		return gatherProperties;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Acct other = (Acct) obj;
		if (getId() == null) {
			if (other.getId() != null)
				return false;
		} else if (!getId().equals(other.getId()))
			return false;
		return true;
	}
}
